package com.cspg.ssss.controller;

import com.alibaba.fastjson.JSONObject;
import com.cspg.ssss.config.WeixinProperties;
import com.cspg.ssss.domain.AddScoreDept;
import com.cspg.ssss.domain.CheckDept;
import com.cspg.ssss.domain.UserDetailInfoEntity;
import com.cspg.ssss.domain.UserEntity;
import com.cspg.ssss.service.*;
import com.cspg.ssss.util.StringConvertUtil;
import com.cspg.ssss.vo.DepartVo;
import com.cspg.ssss.vo.ResultVo;
import com.cspg.ssss.vo.ResultVoUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.security.MessageDigest;
import java.util.*;

@RestController
@RequestMapping("/wxapi")
public class WxController {
    private static Logger log = LoggerFactory.getLogger(WxController.class.getName());

    @Autowired
    WeixinService wxService;

    @Autowired
    WxUserService wxUserService;

    @Autowired
    WeixinProperties wxProperties;

    @Autowired
    WxDepartmentService departmentService;

    @Autowired
    GradeRoleUserService gradeRoleUserService;

    @Autowired
    CheckDeptService checkDeptService;

    /**
     * 获取企业微信配置验证信息
     * @param param
     * @return
     * @throws Exception
     */
    @PostMapping("/getWxConfig")
    public ResultVo getWxConfig(@RequestBody Map<String, String> param) throws Exception {

        String corpid = wxProperties.getCorpid();
        String secret = wxProperties.getSecret();
        log.debug("CorpId = " + corpid + "; Secret = " + secret);

        // 获取企业应用access_token
        String token = wxService.getToken(corpid, secret);
        if(token == null)
        {
            ResultVo retVo = ResultVoUtil.error("1001", "获取企业应用access_token失败");
            return retVo;
        }

        // 获取企业应用jsapi_ticket
        String jsapiTicket = wxService.getTicket(token);
        if(jsapiTicket == null)
        {
            ResultVo retVo = ResultVoUtil.error("1002", "获取企业应用jsapi_ticket失败");
            return retVo;
        }

        // 生成应用权限签名
        String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填，生成签名的时间戳
        String nonceStr = UUID.randomUUID().toString(); // 必填，生成签名的随机串

        // 注意这里参数名必须全部小写，且必须有序
        String sign = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + param.get("url");
        log.debug("SignString = "+ sign);
        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
        crypt.reset();
        crypt.update(sign.getBytes("UTF-8"));
        String signature = StringConvertUtil.byteToHex(crypt.digest());

        // 组装微信配置对象，返回前端
        JSONObject retObj = new JSONObject();
        retObj.put("appId",corpid);
        retObj.put("timestamp", timestamp);
        retObj.put("nonceStr", nonceStr);
        retObj.put("signature", signature);
        ResultVo retVo = ResultVoUtil.success("0000", retObj);
        return retVo;
    }

    /**
     * 获取企业微信配置验证信息,包括ticket和AgentConfig需要的签名等
     * @param param
     * @return
     * @throws Exception
     */
    @PostMapping("/getWxConfigWithAgentConfig")
    public ResultVo getWxConfigWithAgentConfig(@RequestBody Map<String, String> param) throws Exception {

        String corpid = wxProperties.getCorpid();
        String secret = wxProperties.getSecret();
        String agentId = wxProperties.getAgentId();
        log.debug("CorpId = " + corpid + "; Secret = " + secret + "; AgentId = " + agentId);

        // 获取企业应用access_token
        String token = wxService.getToken(corpid, secret);
        if(token == null)
        {
            ResultVo retVo = ResultVoUtil.error("1001", "获取企业应用access_token失败");
            return retVo;
        }

        // 获取企业应用jsapi_ticket
        String jsapiTicket = wxService.getTicket(token);
        if(jsapiTicket == null)
        {
            ResultVo retVo = ResultVoUtil.error("1002", "获取企业应用jsapi_ticket失败");
            return retVo;
        }

        // 生成应用权限签名
        String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填，生成签名的时间戳
        String nonceStr = UUID.randomUUID().toString(); // 必填，生成签名的随机串

        // 注意这里参数名必须全部小写，且必须有序
        String sign = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + param.get("url");
        log.debug("SignString = "+ sign);
        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
        crypt.reset();
        crypt.update(sign.getBytes("UTF-8"));
        String signature = StringConvertUtil.byteToHex(crypt.digest());

        //计算agentConfig所需签名
        // 获取企业应用jsapi_ticket
        String jsapiTicketAgentConfig = wxService.getAppTicket(agentId,token);
        if(jsapiTicketAgentConfig == null)
        {
            ResultVo retVo = ResultVoUtil.error("1003", "获取企业应用AgentConfig jsapi_ticket失败");
            return retVo;
        }

        // 生成应用权限签名
        String timestampAgentConfig = Long.toString(System.currentTimeMillis() / 1000); // 必填，生成签名的时间戳
        String nonceStrAgentConfig = UUID.randomUUID().toString(); // 必填，生成签名的随机串

        // 注意这里参数名必须全部小写，且必须有序
        String signAgentConfig = "jsapi_ticket=" + jsapiTicketAgentConfig + "&noncestr=" + nonceStrAgentConfig + "&timestamp=" + timestampAgentConfig + "&url=" + param.get("url");
        log.debug("SignString = "+ signAgentConfig);
        MessageDigest cryptAgentConfig = MessageDigest.getInstance("SHA-1");
        cryptAgentConfig.reset();
        cryptAgentConfig.update(signAgentConfig.getBytes("UTF-8"));
        String signatureAgentConfig = StringConvertUtil.byteToHex(cryptAgentConfig.digest());

        // 组装微信配置对象，返回前端
        JSONObject retObj = new JSONObject();
        retObj.put("appId",corpid);
        retObj.put("timestamp", timestamp);
        retObj.put("nonceStr", nonceStr);
        retObj.put("signature", signature);

        retObj.put("agentId",agentId);
        retObj.put("actimestamp", timestampAgentConfig);
        retObj.put("acnonceStr", nonceStrAgentConfig);
        retObj.put("acsignature", signatureAgentConfig);


        ResultVo retVo = ResultVoUtil.success("0000", retObj);
        return retVo;
    }

    /**
     * 获取微信用户信息
     * @param param
     * @return
     * @throws Exception
     */
    @PostMapping("/getWxUserInfo")
    public ResultVo getWxUserInfo(@RequestBody Map<String, String> param) throws Exception {
        String corpid = wxProperties.getCorpid();
        String secret = wxProperties.getSecret();
        log.debug("CorpId = " + corpid + "; Secret = " + secret);

        // 获取企业应用access_token
        String token = wxService.getToken(corpid, secret);
        if(token == null)
        {
            ResultVo retVo = ResultVoUtil.error("1001", "获取企业应用access_token失败");
            return retVo;
        }

        // 获取企业用户Id
        String userId = wxService.getUserId(token, param.get("code"));
        if (userId == null) {
            ResultVo retVo = ResultVoUtil.error("1003", "获取企业用户ID失败");
            return retVo;
        }

        // 获取用户详细信息
        UserEntity en = departmentService.getUserInfoByUserId(userId);//wxUserService.getWxUserInfoByUserId(token, userId);
        if (en == null) {
            ResultVo retVo = ResultVoUtil.error("1004", "获取企业用户ID失败");
            return retVo;
        }
        ResultVo retVo = ResultVoUtil.success("success",en);
        return retVo;
    }

    @GetMapping("/getCurUserInfo")
    public ResultVo getCurUserInfo(String code){
        String corpid = wxProperties.getCorpid();
        String secret = wxProperties.getSecret();
        log.debug("CorpId = " + corpid + "; Secret = " + secret);

        // 获取企业应用access_token
        String token = wxService.getToken(corpid, secret);
        if(token == null)
        {
            ResultVo retVo = ResultVoUtil.error("1001", "获取企业应用access_token失败");
            return retVo;
        }

        // 获取企业用户Id
        String userId = wxService.getUserId(token, code);
        if (userId == null) {
            ResultVo retVo = ResultVoUtil.error("1003", "获取企业用户ID失败");
            return retVo;
        }

        //String userId = "xiongzhenqing";
        UserEntity en = departmentService.getUserInfoByUserId(userId);
        if (en == null) {
            ResultVo retVo = ResultVoUtil.error("1004", "获取企业用户详情信息失败");
            return retVo;
        }

        HashMap<String,Object> usercondition = new HashMap<String, Object>();
        usercondition.put("userid",en.getUser_id());
        List<UserDetailInfoEntity> userList = departmentService.getDepartmentUserList(usercondition);
//        List<String> departsls = new ArrayList<String>();
//        if(userList != null && userList.size() > 0){
//            for(int i=0;i<userList.size();i++){
//                departsls.add(userList.get(i).getDepartment_displaypath());
//            }
//        }
//        List<AddScoreDept> userScoreDept = new ArrayList<AddScoreDept>();
//        if(departsls.size()>0){
//            Map<String,Object> scondition = new HashMap<String,Object>();
//            scondition.put("dept_user",departsls);
//            userScoreDept = gradeRoleUserService.getAddScoreDepts(scondition);
//        }

        JSONObject userDepts = getCheckDeptByUserid(en.getUser_id());

        JSONObject obj = new JSONObject();
        obj.put("userid",en.getUser_id());
        obj.put("username",en.getUser_name());
        obj.put("super_admin",false);
        obj.put("grade_approve",false);
        obj.put("grade_user",false);
        obj.put("depart_admin",false);
        obj.put("roles",userDepts);

        ResultVo retVo = ResultVoUtil.success("success",obj);
        return retVo;
    }


    @GetMapping("/getCheckDept")
    public ResultVo getCheckDept(String userId){
        JSONObject userDepts = getCheckDeptByUserid(userId);
        ResultVo retVo = ResultVoUtil.success("success",userDepts);
        return retVo;
    }
    /**
     * 根据用户id获取用户所在的考核部门与被考核部门
     * @param uid
     * @return
     */
    private JSONObject getCheckDeptByUserid(String uid){
        JSONObject retObj = new JSONObject();

        //获取当前人所在部门列表
        HashMap<String,Object> usercondition = new HashMap<String, Object>();
        usercondition.put("userid",uid);
        List<UserDetailInfoEntity> userList = departmentService.getDepartmentUserList(usercondition);

        //通过过滤获取当前人所在的考核部门，被考核部门
        Map<String,Object> condition = new HashMap<String, Object>();

        JSONObject c2uObj = new JSONObject();

        condition.put("depart_type",0);
        condition.put("check_type",0);
        List<CheckDept> c2ucdeptls = checkDeptService.getCheckDeptByCondition(condition);

        List<DepartVo> c2u_assess_dept = getDepartVoListWithSubDept(userList,c2ucdeptls);
        c2uObj.put("assess_dept",c2u_assess_dept);

        condition.put("depart_type",1);
        condition.put("check_type",0);
        List<CheckDept> c2udeptls = checkDeptService.getCheckDeptByCondition(condition);
        List<DepartVo> c2u_dept = getDepartVoList(userList,c2udeptls);
        c2uObj.put("dept",c2u_dept);
        retObj.put("corp",c2uObj);

        JSONObject u2deptObj = new JSONObject();

        condition.put("depart_type",0);
        condition.put("check_type",1);
        List<CheckDept> u2dcdeptls = checkDeptService.getCheckDeptByCondition(condition);
        List<DepartVo> u2dept_assess_dept = getDepartVoList(userList,u2dcdeptls);
        u2deptObj.put("assess_dept",u2dept_assess_dept);

        condition.put("depart_type",1);
        condition.put("check_type",1);
        List<CheckDept> u2ddeptls = checkDeptService.getCheckDeptByCondition(condition);
        List<DepartVo> u2dept_dept = getDepartVoList(userList,u2ddeptls);
        u2deptObj.put("dept",u2dept_dept);
        retObj.put("dept",u2deptObj);
        return retObj;

    }

    private List<DepartVo> getDepartVoList(List<UserDetailInfoEntity> userDepts,List<CheckDept> chkDepts){
        List<DepartVo> retLs = new ArrayList<DepartVo>();
        if(chkDepts != null && chkDepts.size() > 0){
            for(int i=0;i<chkDepts.size();i++){
                for(int j=0;j<userDepts.size();j++){
                    if(userDepts.get(j).getDepartment_displaypath().equals(chkDepts.get(i).getDepart_path())){
                        DepartVo vo = new DepartVo();
                        vo.setId(chkDepts.get(i).getId());
                        vo.setDepartment_path(chkDepts.get(i).getDepart_path());
                        retLs.add(vo);
                    }
                }
            }
        }
        return retLs;
    }

    private List<DepartVo> getDepartVoListWithSubDept(List<UserDetailInfoEntity> userDepts,List<CheckDept> chkDepts){
        List<DepartVo> retLs = new ArrayList<DepartVo>();
        if(chkDepts != null && chkDepts.size() > 0){
            for(int i=0;i<chkDepts.size();i++){
                for(int j=0;j<userDepts.size();j++){
                    if(userDepts.get(j).getDepartment_displaypath().startsWith(chkDepts.get(i).getDepart_path())){
                        DepartVo vo = new DepartVo();
                        vo.setId(chkDepts.get(i).getId());
                        vo.setDepartment_path(chkDepts.get(i).getDepart_path());
                        retLs.add(vo);
                    }
                }
            }
        }
        return retLs;
    }

    @GetMapping("getAddScoreDeptByUserid")
    public ResultVo getAddScoreDeptByUserid(String uid){
        HashMap<String,Object> usercondition = new HashMap<String, Object>();
        usercondition.put("userid",uid);
        List<UserDetailInfoEntity> userList = departmentService.getDepartmentUserList(usercondition);
        List<String> departsls = new ArrayList<String>();
        if(userList != null && userList.size() > 0){
            for(int i=0;i<userList.size();i++){
                departsls.add(userList.get(i).getDepartment_displaypath());
            }
        }
        List<AddScoreDept> userScoreDept = new ArrayList<AddScoreDept>();
        if(departsls.size()>0){
            Map<String,Object> scondition = new HashMap<String,Object>();
            scondition.put("dept_user",departsls);
            userScoreDept = gradeRoleUserService.getAddScoreDepts(scondition);
        }

        ResultVo retVo = ResultVoUtil.success("success",userScoreDept);
        return retVo;
    }

    @GetMapping("getCheckDeptsByUserid")
    public ResultVo getCheckDeptsByUserid(String uid){

        UserEntity en = departmentService.getUserInfoByUserId(uid);
        if (en == null) {
            ResultVo retVo = ResultVoUtil.error("1004", "获取企业用户详情信息失败");
            return retVo;
        }

        HashMap<String,Object> usercondition = new HashMap<String, Object>();
        usercondition.put("userid",en.getUser_id());
        List<UserDetailInfoEntity> userList = departmentService.getDepartmentUserList(usercondition);

        JSONObject userDepts = getCheckDeptByUserid(en.getUser_id());

        JSONObject obj = new JSONObject();
        obj.put("userid",en.getUser_id());
        obj.put("username",en.getUser_name());
        obj.put("super_admin",false);
        obj.put("grade_approve",false);
        obj.put("grade_user",false);
        obj.put("depart_admin",false);
        obj.put("roles",userDepts);

        ResultVo retVo = ResultVoUtil.success("success",obj);
        return retVo;
    }
}
